<template>
	<view
		v-if="loading"
		:style="{
			width: windowWinth + 'px',
			height: windowHeight + 'px',
			backgroundColor: bgColor,
			position: 'absolute',
			left: left + 'px',
			top: top + 'px',
			zIndex: 9998,
			overflow: 'hidden'
		}"
		@touchmove.stop.prevent
	>
		<view
			v-for="(item, index) in RectNodes"
			:key="$u.guid()"
			:class="[animation ? 'skeleton-fade' : '']"
			:style="{
				width: item.width + 'px',
				height: item.height + 'px',
				backgroundColor: elColor,
				position: 'absolute',
				left: item.left - left + 'px',
				top: item.top - top + 'px'
			}"
		></view>
		<view
			v-for="(item, index) in circleNodes"
			:key="$u.guid()"
			:class="animation ? 'skeleton-fade' : ''"
			:style="{
				width: item.width + 'px',
				height: item.height + 'px',
				backgroundColor: elColor,
				borderRadius: item.width / 2 + 'px',
				position: 'absolute',
				left: item.left - left + 'px',
				top: item.top - top + 'px'
			}"
		></view>
		<view
			v-for="(item, index) in filletNodes"
			:key="$u.guid()"
			:class="animation ? 'skeleton-fade' : ''"
			:style="{
				width: item.width + 'px',
				height: item.height + 'px',
				backgroundColor: elColor,
				borderRadius: borderRadius + 'rpx',
				position: 'absolute',
				left: item.left - left + 'px',
				top: item.top - top + 'px'
			}"
		></view>
	</view>
</template>

<script>
/**
 * skeleton 骨架屏
 * @description 骨架屏一般用于页面在请求远程数据尚未完成时，页面用灰色块预显示本来的页面结构，给用户更好的体验。
 * @tutorial https://www.uviewui.com/components/skeleton.html
 * @property {String} el-color 骨架块状元素的背景颜色（默认#e5e5e5）
 * @property {String} bg-color 骨架组件背景颜色（默认#fff）
 * @property {Boolean} animation 骨架块是否显示动画效果（默认false）
 * @property {String Number} border-radius u-skeleton-fillet类名元素，对应的骨架块的圆角大小，单位rpx（默认10）
 * @property {Boolean} loading 是否显示骨架组件，请求完成后，将此值设置为false（默认true）
 * @example <u-skeleton :loading="true" :animation="true"></u-skeleton>
 */
export default {
	name: 'u-skeleton',
	props: {
		// 需要渲染的元素背景颜色，十六进制或者rgb等都可以
		elColor: {
			type: String,
			default: '#e5e5e5'
		},
		// 整个骨架屏页面的背景颜色
		bgColor: {
			type: String,
			default: '#fff'
		},
		// 是否显示加载动画
		animation: {
			type: Boolean,
			default: false
		},
		// 圆角值，只对类名为u-skeleton-fillet的元素生效，为数值，不带单位
		borderRadius: {
			type: [String, Number],
			default: '10'
		},
		// 是否显示骨架，true-显示，false-隐藏
		loading: {
			type: Boolean,
			default: true
		}
	},
	data() {
		return {
			windowWinth: 750, // 骨架屏宽度
			windowHeight: 1500, // 骨架屏高度
			filletNodes: [], // 圆角元素
			circleNodes: [], // 圆形元素
			RectNodes: [], // 矩形元素
			top: 0,
			left: 0
		};
	},
	methods: {
		// 查询各节点的信息
		selecterQueryInfo() {
			// 获取整个父组件容器的高度，当做骨架屏的高度
			// 在微信小程序中，如果把骨架屏放入组件中使用的话，需要调in(this)上下文为父组件才有效
			let query = '';
			// #ifdef MP-WEIXIN
			query = uni.createSelectorQuery().in(this.$parent);
			// #endif
			// #ifndef MP-WEIXIN
			query = uni.createSelectorQuery();
			// #endif
			query
				.selectAll('.u-skeleton')
				.boundingClientRect()
				.exec((res) => {
					this.windowHeight = res[0][0].height;
					this.windowWinth = res[0][0].width;
					this.top = res[0][0].bottom - res[0][0].height;
					this.left = res[0][0].left;
				});
			// 矩形骨架元素
			this.getRectEls();
			// 圆形骨架元素
			this.getCircleEls();
			// 圆角骨架元素
			this.getFilletEls();
		},
		// 矩形元素列表
		getRectEls() {
			let query = '';
			// 在微信小程序中，如果把骨架屏放入组件中使用的话，需要调in(this)上下文为父组件才有效
			// #ifdef MP-WEIXIN
			query = uni.createSelectorQuery().in(this.$parent);
			// #endif
			// #ifndef MP-WEIXIN
			query = uni.createSelectorQuery();
			// #endif
			query
				.selectAll('.u-skeleton-rect')
				.boundingClientRect()
				.exec((res) => {
					this.RectNodes = res[0];
				});
		},
		// 圆角元素列表
		getFilletEls() {
			let query = '';
			// 在微信小程序中，如果把骨架屏放入组件中使用的话，需要调in(this)上下文为父组件才有效
			// #ifdef MP-WEIXIN
			query = uni.createSelectorQuery().in(this.$parent);
			// #endif
			// #ifndef MP-WEIXIN
			query = uni.createSelectorQuery();
			// #endif
			query
				.selectAll('.u-skeleton-fillet')
				.boundingClientRect()
				.exec((res) => {
					this.filletNodes = res[0];
				});
		},
		// 圆形元素列表
		getCircleEls() {
			let query = '';
			// 在微信小程序中，如果把骨架屏放入组件中使用的话，需要调in(this)上下文为父组件才有效
			// #ifdef MP-WEIXIN
			query = uni.createSelectorQuery().in(this.$parent);
			// #endif
			// #ifndef MP-WEIXIN
			query = uni.createSelectorQuery();
			// #endif
			query
				.selectAll('.u-skeleton-circle')
				.boundingClientRect()
				.exec((res) => {
					this.circleNodes = res[0];
				});
		}
	},
	// 组件被挂载
	mounted() {
		// 获取系统信息
		let systemInfo = uni.getSystemInfoSync();
		this.windowHeight = systemInfo.windowHeight;
		this.windowWinth = systemInfo.windowWidth;
		this.selecterQueryInfo();
	}
};
</script>

<style lang="scss" scoped>
@import '../../libs/css/style.components.scss';

.skeleton-fade {
	width: 100%;
	height: 100%;
	background: rgb(194, 207, 214);
	animation-duration: 1.5s;
	animation-name: blink;
	animation-timing-function: ease-in-out;
	animation-iteration-count: infinite;
}

@keyframes blink {
	0% {
		opacity: 1;
	}

	50% {
		opacity: 0.4;
	}

	100% {
		opacity: 1;
	}
}
</style>
